import React,{ axios, useState, useEffect } from 'react';
import { Image, Button, Modal, message, ConfigProvider } from 'antd';
import zh_CN from 'antd/lib/locale-provider/zh_CN';
import { CheckOutlined } from '@ant-design/icons';
import "./ResourceManage.less";
// base64图片资源
import { defaultImage } from '../../../assets/tools/base64-image';
// 面包屑导航
import BreadNav from '../../../components/BreadNav/BreadNav';
// 订阅发布模块
import PubSub from 'pubsub-js';

/**
 * 资源管理组件页
 */
function ResourceManage(props) {
    // 图片预览
    const [preImage, setPreImage] = useState(defaultImage);
    // 上传原图的宽高
    const [imageNaturalWidth, setImageNaturalWidth] = useState(0);
    const [imageNaturalHeight, setImageNaturalHeight] = useState(0);
    // 全部分类项
    const [allClassifyItems, setAllClassifyItems] = useState([]);
    // 主分类类目
    const [typeMainItems, setTypeMainItems] = useState([]);
    // 子分类类目
    const [typeSubItems, setTypeSubItems] = useState([]);
    // 选中的主分类
    const [selectedTypeMain, setSelectedTypeMain] = useState('图片');
    // 选中的子分类
    const [selectedTypeSub, setSelectedTypeSub] = useState('');
    // 资源文件信息
    const [resoInfo, setResoInfo] = useState({});
    // 文件名
    const [fileName, setFileName] = useState('');
    // 资源描述信息（备注信息）
    const [description, setDescription] = useState('');

    // 当前页面是否为修改页面
    const [isModifyPage] = useState(props.location.state ? true: false);
    // 是否显示图片预览
    const [showPreImage, setShowPreImage] = useState(isModifyPage);

    /**
     * 图片上传后的预览事件
     */
    const previewImageEvent = e => {
        // 上传的资源
        const uploadResource = e.target.files[0];
        console.log(uploadResource);

        // 如果上传的资源为空，则中止后续操作（更改上传的时候取消）
        if(!uploadResource) {
            // 清空资源信息
            setResoInfo({});
            // 隐藏预览图并还原预览图的状态
            setPreImage(defaultImage);
            setShowPreImage(false);
            return;
        }

        // 设置资源信息
        setResoInfo(uploadResource);

        // 判断是否为图片
        if(uploadResource.type.includes('image')) {
            // 判断大小
            if(uploadResource.size > 1024 * 5000) {
                message.error({
                    content: '图片的大小应该限制在5Mb以内',
                    style: {
                        marginTop: '30vh'
                    }
                });
                e.target.value = '';
                return;
            }
            // 显示预览图
            setShowPreImage(true);

            // 实例化文件读取API
            const reader = new FileReader();
            // 将文件读取为DataURL（base64编码）
            reader.readAsDataURL(uploadResource);
            // 读取完成后
            reader.onload = function() {
                // 设置显示的图片
                setPreImage(this.result);
                // 打印图片尺寸
                let virtualPic = document.createElement("img");
                virtualPic.src = this.result;
                virtualPic.onload = function () {
                    // 设置获取到的原图宽高
                    setImageNaturalWidth(virtualPic.naturalWidth);
                    setImageNaturalHeight(virtualPic.naturalHeight);
                    
                    // 移除虚拟图片元素释放内存
                    virtualPic = null;
                }
            };
            // 读取错误
            reader.onerror = function() {
                message.error({
                    content: '图片的类型不能进行预览',
                    style: {
                        marginTop: '30vh'
                    }
                });
            }
        }
    }

    /**
     * 设置子分类联动事件
     */
    const setSubClassifyItems = e => {
        // 主菜单选中的值
        const choiceVal = e.target.value;

        // 设置主菜单的选中状态对应的文本
        setSelectedTypeMain(choiceVal);

        // 查询出主分类选择对应的项
        const correspondingOption = allClassifyItems.find(option => 
            option.mainType === choiceVal
        );
        
        // 设置子分类下拉菜单的选项
        setTypeSubItems(correspondingOption.subType);
        // 设置子分类菜单选中的
        setSelectedTypeSub(correspondingOption.subType[0]);
    }

    // 子分类的选择事件
    const subClassifyChoose = e => {
        setSelectedTypeSub(e.target.value)
    }

    /**
     * 设置文件名、备注信息的事件
     */
    const setFieldsValue = e => {
        // 表单项名称
        const formItemName = e.target.name;
        // 输入的值
        const inputValue = e.target.value;

        // 如果为文件名
        if(formItemName === 'filename') {
            // 设置该项对应的状态值
            setFileName(inputValue);
        }
        // 如果为备注信息
        else if(formItemName === 'description') {
            // 设置该项对应的状态值
            setDescription(inputValue);
        }
        else {
            console.error('该字段并不受该事件监控，请检查配置');
        }
    }

    /**
     * 确认输入的信息
     */
    const confirmFormInfo = () => {
        // 判断资源文件是否上传
        if(!resoInfo.name) {
            message.error({
                content: '您还没有上传资源呢',
                style: {
                    marginTop: '30vh'
                }
            });
            return;
        }

        // 资源信息模态框
        Modal.info({
            title: '确认资源信息',
            content: (
                <div className="confirm-info-panel">
                    <p>
                        <span className="label">资源原名</span>
                        <span className="text">{resoInfo.name}</span>
                    </p>
                    <p>
                        <span className="label">资源类型</span>
                        <span className="text">{resoInfo.type}</span>
                    </p>
                    <p>
                        <span className="label">资源体积</span>
                        <span className="text">{resoInfo.size}</span>
                    </p>
                    <p>
                        <span className="label">最后修改日期</span>
                        <span className="text">{resoInfo.lastModifiedDate.toLocaleString()}</span>
                    </p>
                    <p>
                        <span className="label">所属分类</span>
                        <span className="text">{selectedTypeMain} - {selectedTypeSub}</span>
                    </p>
                    <p>
                        <span className="label">文件名</span>
                        <span className="text">{fileName || <i>您没有写 -_-!</i>}</span>
                    </p>
                    <p>
                        <span className="label">备注信息</span>
                        <span className="text">{description || <i>您没有写 -_-!</i>}</span>
                    </p>
                </div>
            ),
            width: 'max-content'
        });
    }

    /**
     * 表单信息上传
     */
    const formInfoUpload = e => {
        e.preventDefault();
        // 使用 FormData 实例来处理表单数据
        const formData = new FormData();

        // 资源上传等待提示
        const loadingMessage = message.loading('资源上传中', 0);

        // 获取表单上传的资源信息
        const formObj = e.target;

        /**** 如果为资源创建页 ****/
        if(!isModifyPage) {
            // 获取和处理上传的资源
            const theFile = formObj.resource.files[0];
            formData.append('uploadfile', theFile, theFile.name);
    
            // 所属主-子分类
            const typeMain = formObj.typeMain.value;
            const typeSub = formObj.typeSub.value;
            // 获取并设置将上传的资源信息
            formData.append('resoOriginName',resoInfo.name);
            formData.append('resoType',resoInfo.type);
            formData.append('resoSize',resoInfo.size);
            formData.append('imageNaturalWidth',imageNaturalWidth);
            formData.append('imageNaturalHeight',imageNaturalHeight);
            formData.append('lastModifiedDate',resoInfo.lastModifiedDate);
            // 获取并设置用户输入的资源信息
            formData.append('classify',typeMain);
            formData.append('classify',typeSub);
            formData.append('fileName', fileName);
            formData.append('description', description);
            formData.append('uploadDate',new Date());
            // 上传到服务器
            axios.post('/api/resource/uploadp_picture', formData, {
                mimeType: "multipart/form-data"
            }).then(res => {
                // 关闭等待上传消息框
                setTimeout(loadingMessage, 1800);

                // 服务器返回数据
                const resData = res.data;

                // 获取主-子分类
                const [mainClassify, subClassify] = resData.resourceInfo.classify;

                // 路由路径设置
                let route_lev2 = '';
                switch (mainClassify) {
                    case '图片':
                        route_lev2 = 'pictures';
                        break;
                    default:
                        route_lev2 = 'statistichome';
                        break;
                }
                
                // 上传成功
                if(resData.result === 'success') {
                    // 成功后的操作提示
                    Modal.confirm({
                        title: '资源上传成功',
                        icon: <CheckOutlined style={{color: '#36be47'}} />,
                        content: '是否前往查看上传的资源？',
                        okText: '前往查看',
                        cancelText: '继续上传',
                        onOk() {
                            // 发布一个左侧导航展开的事件
                            PubSub.publish('setOpenMenu', route_lev2);
                            props.history.push(`/home/${route_lev2}?classifyName=${subClassify}`);
                        },
                        onCancel() {
                            // 重置表单信息（部分表单信息受控，需要手动处理）
                            formObj.reset();

                            // 重置各个状态
                            setPreImage(defaultImage);
                            setSelectedTypeMain('图片');
                            setSelectedTypeSub('风景');
                            setFileName('');
                            setDescription('');
                            setShowPreImage(false);
                        }
                    });
                }
            }).catch(err => {
                // 关闭等待上传消息框
                setTimeout(loadingMessage, 1800);
                message.error('上传资源发生未知错误：', err);
            });
        }
        /**** 如果为资源修改页 ****/
        else {
            // 获取和处理上传的资源
            const theFile = formObj.resource.files[0];
            
            // 如果图片文件经过了修改
            if(theFile) {
                // 资源文件的相关信息
                formData.append('uploadfile', theFile, theFile.name);
                formData.append('resoOriginName',resoInfo.name);
                formData.append('resoType',resoInfo.type);
                formData.append('resoSize',resoInfo.size);
                formData.append('lastModifiedDate',resoInfo.lastModifiedDate);
            }

            // 所属主-子分类
            const typeMain = formObj.typeMain.value;
            const typeSub = formObj.typeSub.value;
           
            // 获取用户输入的资源信息
            formData.append('resourceID', props.location.state._id);
            formData.append('classify', typeMain);
            formData.append('classify', typeSub);
            formData.append('fileName', fileName);
            formData.append('description', description);
            formData.append('uploadDate',new Date());

            // 调用更新资源信息的接口
            axios.post('/api/resource/edit_picture', formData, {
                mimeType: "multipart/form-data"
            }).then(res => {
                // 关闭等待上传消息框
                setTimeout(loadingMessage, 1800);

                // 服务器返回数据
                const resData = res.data;

                // 路由路径设置
                let route_lev2 = '';
                switch (typeMain) {
                    case '图片':
                        route_lev2 = 'pictures';
                        break;
                    default:
                        route_lev2 = 'statistichome';
                        break;
                }
                
                // 上传成功
                if(resData.result === 'success') {
                    // 成功后的操作提示
                    Modal.confirm({
                        title: '资源更改成功',
                        icon: <CheckOutlined style={{color: '#36be47'}} />,
                        content: '是否前往查看更改后的资源？',
                        okText: '前往查看',
                        cancelText: '上传新资源',
                        onOk() {
                            // 发布一个左侧导航展开的事件
                            PubSub.publish('setOpenMenu', route_lev2);
                            props.history.push(`/home/${route_lev2}?classifyName=${typeSub}`);
                        },
                        onCancel() {
                            // 重置表单信息（部分表单信息受控，需要手动处理）
                            formObj.reset();

                            // 重置各个状态
                            setPreImage(defaultImage);
                            setSelectedTypeMain('图片');
                            setSelectedTypeSub('风景');
                            setFileName('');
                            setDescription('');
                            setShowPreImage(false);
                        }
                    });
                }
            }).catch(err => {
                // 关闭等待上传消息框
                setTimeout(loadingMessage, 1800);
                // 打印错误
                console.error('资源修改出现了错误：', err)
            });
        }
    }

    /**
     * 生命周期
     */
    useEffect(() => {
        // 载入资源管理项
        axios.get('/options/resource-manage-option.json').then(res => {
            // 获取全部分类
            const resourceClassifyItems = res.data.resourceClassifyItems;

            // 设置所有资源分类
            setAllClassifyItems(resourceClassifyItems);

            // 获取主分类名称列表
            const mainTypeName = resourceClassifyItems.map(classif => classif.mainType);

            // 设置主分类下拉菜单选项
            setTypeMainItems(mainTypeName);

            // 获取子分类名称列表
            const subTypeArr = resourceClassifyItems[0].subType;
            // 设置子分类菜单
            setTypeSubItems(subTypeArr);

            /**** 如果是资源创建页 ****/
            if(!isModifyPage) {
                // 设置子分类菜单选中项
                setSelectedTypeSub(subTypeArr[0]);
            }
            /**** 如果是资源修改页 ****/
            else {
                // 解构出资源的信息项
                const {
                    filePreviewSavePath, 
                    classify,
                    fileName,
                    description
                } = props.location.state;

                // 设置预览图
                setPreImage(filePreviewSavePath);
                // 设置主分类菜单选中项
                setSelectedTypeMain(classify[0])
                // 设置子分类菜单选中项
                setSelectedTypeSub(classify[1]);
                // 设置文件名
                setFileName(fileName);
                // 设置描述信息
                setDescription(description);
            }
        });
    },[props.location.state, isModifyPage]);
    
    return (
        <div className="ResourceManage">
            {/* 面包屑导航 */}
            <BreadNav locations={props.location}/>
            
            {/* 资源管理表单 */}
            <div className="manage-panel">
                <ConfigProvider locale={zh_CN}>
                    <form 
                        className="resource-manage-form"
                        method="POST"
                        encType="multipart/form-data"
                        autoComplete="off"
                        onSubmit={formInfoUpload}
                    >
                        {isModifyPage ? <h2>资源文件修改</h2> : <h2>资源文件上传</h2>}

                        {/* <div className="form-line small-gap"> */}
                        <div className={showPreImage ? "form-line small-gap" : "form-line"}>
                            <label>上传资源</label>
                            <input 
                                onChange={previewImageEvent}
                                name="resource"
                                type="file"
                                // 允许文件夹上传
                                // webkitdirectory="true"
                                required={!isModifyPage}
                            />
                            <span className="reqired">*</span>
                        </div>

                        {showPreImage ?
                            (<div className="form-line">
                                <div className="preview-image-container offset-left">
                                    <Image
                                        className="preview-image"
                                        src={preImage}
                                        fallback={defaultImage}
                                        style={
                                            imageNaturalWidth <= 304 ? 
                                            {
                                                width: 'auto',
                                                height: 'auto',
                                                objectFit: 'contain'
                                            } : ''
                                        }
                                    />
                                </div>
                            </div>) : ''
                        }

                        <div className="form-line large-gap">
                            <label>所属分类</label>
                            <select 
                                name="typeMain" 
                                className="select-inline" 
                                value={selectedTypeMain}
                                required
                                onChange={setSubClassifyItems}
                            >
                                {typeMainItems.map(item => 
                                   <option key={item} value={item}>{item}</option>
                                )}
                            </select>
                            <select 
                                name="typeSub" 
                                className="select-inline" 
                                value={selectedTypeSub}
                                required
                                onChange={subClassifyChoose}
                            >
                                {typeSubItems.map(item => 
                                   <option key={item} value={item}>{item}</option>
                                )}
                            </select>
                            <span className="reqired">*</span>
                            {/* 根据不同的选择返回不同的分类提示 */}
                            {typeTipsSwitch(selectedTypeMain)}
                        </div>

                        <div className="form-line">
                            <label>文件名</label>
                            <input 
                                name="filename" 
                                placeholder="请输入文件名，便于资源识别" 
                                required
                                value={fileName}
                                onChange={setFieldsValue}
                            />
                            <span className="reqired">*</span>
                        </div>

                        <div className="form-line">
                            <label>备注信息</label>
                            <textarea 
                                name="description" 
                                rows="4" 
                                placeholder="您可以在这里留下资源的来源信息或其它的任意描述"
                                value={description}
                                onChange={setFieldsValue}
                            ></textarea>
                        </div>

                        <div className="form-line btn-group">
                            <div className="offset-left">
                                <Button 
                                    type="default" 
                                    htmlType="button" 
                                    size="large"
                                    onClick={confirmFormInfo}
                                >确认信息</Button>
                                {isModifyPage ?
                                    <Button 
                                        type="primary" 
                                        htmlType="submit" 
                                        size="large"
                                    >确认修改</Button> :
                                    <Button 
                                        type="primary" 
                                        htmlType="submit" 
                                        size="large"
                                    >上传资源</Button>
                                }
                            </div>
                        </div>
                    </form>
                </ConfigProvider>
            </div>
        </div>
    )
}

/**
 * 根据所属主分类返回不同的提示
 * @param {String} type 所选择的主分类名称
 */
function typeTipsSwitch(type) {
    switch (type) {
        case '图片':
            return <div className="tips">只能上传常见的图片格式，首先建议为 JPEG、PNG 等格式</div>
        case '插件库':
            return <div className="tips">只能上传 JS、CSS 等能够被浏览器直接解析的文件</div>
        case '项目存档':
            return <div className="tips">只能上传 RAR 或 ZIP 的格式项目压缩包 </div>
        case '资料文档':
            return <div className="tips">可以上传文本文件、Word、Excel、PPT、Markdown、xmind 等常见文档格式</div>
        case '视频短片':
            return <div className="tips">由于 Chrome 浏览器限制，只能上传 MP4、MKV 和 WebM 格式的视频</div>
        default:
            return '';
    }
    
}

export default ResourceManage
